import { ref } from 'vue';
import { defineStore } from 'pinia';
import api from '@/http/api';
import tool from "@/utils/tool";
import { ElMessage } from "element-plus";

const components = import.meta.glob(['@/admin/!(components)/**/*.vue', '@/admin/!(components)/*.vue']);
const baseRoutes = [{
  name: 'layout',
  path: '/layout/index',
  text: 'layout',
  component: () => import('@/admin/layout/index.vue'),
  children: []
}, {
  name: 'visualEditor',
  path: '/visual/editor',
  component: () => import('@/admin/visual/editor.vue')
}, {
  name: 'dashboardEditor',
  path: '/dashboard/editor',
  component: () => import('@/admin/dashboard/editor.vue')
}, {
  name: 'dashboard',
  path: '/dashboard/:dashboardId',
  text: '数据大屏',
  meta: {
    title: '数据大屏',
  },
  component: () => import('@/business/dashboard/index.vue')
}, {
  name: 'console',
  path: '/console/index',
  text: '日志查看',
  component: () => import('@/admin/console/index.vue')
}, {
  name: 'notfound',
  path: '/:pathMatch(.*)',
  text: '访问地址不存在',
  component: () => import('@/error/404.vue')
}];

const getComponent = async(compName, path) => {
  const keys = Object.keys(components);
  const matchKeys = keys.filter((key) => {
    return key.replace('/src/admin', '').replace('/src', '').replace('.vue', '') === path;
  });

  const component = components[matchKeys[0]];
  return !component ? null : await component().then(comp => ({
    ...comp.default,
    name: compName
  }));
};

const formatRoute = async(routes, routeMap, routerList) => {
  for (let item of routes) {
    item.name = item.name || item.id;
    item.path = item.href || item.path || '';
    item.meta = item.meta || {};
    item.meta.keepAlive = (typeof item.keepAlive !== 'undefined')
        ? item.keepAlive : ((typeof item.meta.keepAlive === 'undefined') ? true : item.meta.keepAlive);
    item.meta.title = item.text;
    item.meta.icon = item.data && item.data.icon;
    item.meta.buttons = ((item.data && item.data.privileges) || []);
    item.meta.hidden = item.hidden;
    item.meta.url = item.data && item.data.url;
    if (!item.component && item.path) {
      item.component = await getComponent(item.name, item.path);
    }

    if (item.data && item.data.url) {
      routeMap[item.id] = item;
    }

    if (item.children && item.children.length > 0) {
      await formatRoute(item.children, routeMap, routerList);

      item.children = item.children.filter(ch => !ch.data || ch.data.type !== '2');
      if ((item.children.length === 0
              || item.children.every(ch => typeof ch.data === "undefined" || ch.data == null || ch.data.type === '权限'))
          && ((item.hidden !== true && item.href && item.data && item.data.url && item.data.type !== '权限')
              || (item.data && item.data.type === '页面'))) {
        routerList.push({ label: item.text, value: item.id });
      }
    } else {
      if ((item.hidden !== true && item.href && item.data && item.data.url && item.data.type !== '权限')
          || (item.data && item.data.type === '页面')) {
        routerList.push({ label: item.text, value: item.id });
      }

      delete item.children;
    }
  }
};

export const useRouterStore = defineStore('router', () => {
  const routes = ref([]);
  const routeMap = ({});
  const routerList = ref([]);
  const isInit = ref(false);

  const initRouter = async(router) => {
    if (isInit.value) {
      return false;
    }

    router.getRoutes().forEach(item => {
      item.name && router.removeRoute(item.name);
    });

    const res = await api.post('/system/menu/queryMenuTree');
    if (res.code === '500') {
      ElMessage.error(res.message);
      setTimeout(() => {
        window.location.href = tool.getBaseUrl() + '/choose.html';
      }, 1000);
      return;
    }

    const menuTree = res.data && res.data.children || [];
    if (menuTree.length === 0) {
      ElMessage.error("此子系统未配置菜单！");
      setTimeout(() => {
        window.location.href = tool.getBaseUrl() + '/choose.html?stop=1';
      }, 1000);
      return;
    }

    const routeList = tool.deepClone(baseRoutes) || [];
    routeList[0].children.push(...menuTree);
    await formatRoute(routeList, routeMap, routerList.value);
    routeList.forEach(route => router.addRoute(route));
    routes.value = routeList;
    isInit.value = true;
    return true;
  };

  const getDefaultRoute = (routeList) => {
    if (!routeList || routeList.length === 0) {
      return null;
    }

    for (const route of routeList) {
      if (route.meta && route.meta.defaultShow === '1') {
        return route;
      }

      const temp = getDefaultRoute(route.children);
      if (temp) {
        return temp;
      }
    }

    return null;
  };

  const getFirstRoute = (routeList) => {
    if (!routeList || routeList.length === 0) {
      return null;
    }

    for (const route of routeList) {
      if ((route.href || route.path) && route.name !== 'layout') {
        return route;
      }

      const temp = getFirstRoute(route.children);
      if (temp) {
        return temp;
      }
    }

    return null;
  };

  const getShowRoute = () => {
    const route = getDefaultRoute(routes.value);
    return route ? route : getFirstRoute(routes.value);
  };

  return {
    routes,
    routeMap,
    routerList,
    initRouter,
    getShowRoute,
  };
});

